﻿using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace Firefly.Framework.Input
{
    public class KeyboardManager : HumanInterfaceDevice<KeyboardState>, IHumanInterfaceDevice<KeyboardState>
    {
        public List<Keys> CurrentKeysPressed
        {
            get { return CurrentState.GetPressedKeys().ToList<Keys>(); }
        }
        public List<Keys> PreviousKeysPressed
        {
            get { return PreviousState.GetPressedKeys().ToList<Keys>(); }
        }

        public KeyboardManager()
        {
            DeviceType = DeviceType.Keyboard;
            CurrentState = Keyboard.GetState();
        }

        public bool IsButtonUp(Keys key)
        {
            return CurrentState.IsKeyUp(key);
        }

        public bool WasButtonUp(Keys key)
        {
            return PreviousState.IsKeyUp(key);
        }

        public bool IsButtonDown(Keys key)
        {
            return CurrentState.IsKeyDown(key);
        }

        public bool WasButtonDown(Keys key)
        {
            return PreviousState.IsKeyDown(key);
        }

        public bool WasButtonPressed(Keys key)
        {
            return (PreviousState.IsKeyUp(key) && CurrentState.IsKeyDown(key)) ? true : false;
        }

        public bool WasButtonReleased(Keys key)
        {
            return (PreviousState.IsKeyDown(key) && CurrentState.IsKeyUp(key)) ? true : false;
        }

        public bool WasButtonHeld(Keys key)
        {
            return (PreviousState.IsKeyDown(key) && CurrentState.IsKeyDown(key)) ? true : false;
        }

        #region IHumanInterfaceDevice Members

        public override void RegisterInputMap(IInputMap map)
        {
            (map as IHasInputManager<KeyboardManager>).Manager = this;
            base.RegisterInputMap(map);
        }

        #endregion

        #region IUpdateable Members

        public override void Update(GameTime gameTime)
        {
            if (Enabled)
            {
                PreviousState = CurrentState;
                CurrentState = Keyboard.GetState();

                foreach (IInputMap map in InputMaps)
                {
                    if (map.InputMapType == InputMapType.KeyMap)
                    {
                        map.Update(gameTime);
                    }
                }

                if (CurrentState != PreviousState)
                {
                    NotifyStateChanged(new StateChangedEventArgs<KeyboardState>(CurrentState));
                }
            }
        }

        #endregion
    }
}
